<template>
  <div class="app-container">
    <div class="app-layout">
      <!-- 左侧类别树 -->
      <div class="left-panel">
        <div class="pane">
          <div class="head">
            <span>SQL类别</span>
            <div style="flex: 1;"></div>
            <el-button type="primary" @click="handleAddCategory" size="small" style="margin-right: 12px;">
              <el-icon><Plus /></el-icon>新增类别
            </el-button>
          </div>
          <div class="body">
            <el-tree
              ref="treeRef"
              :data="categoryTreeData"
              :props="defaultProps"
              node-key="id"
              highlight-current
              @node-click="handleCategoryClick"
              @node-contextmenu="handleContextMenu"
              v-loading="categoryLoading"
            >
              <template #default="{ node, data }">
                <span class="custom-tree-node">
                  <span>{{ node.label }}</span>
                  <span class="node-actions">
                    <el-button 
                      link 
                      type="primary" 
                      @click.stop="handleAddSubCategory(data)"
                    >
                      <el-icon><Plus /></el-icon>
                    </el-button>
                  </span>
                </span>
              </template>
            </el-tree>
          </div>
        </div>
      </div>

      <!-- 右侧SQL列表 -->
      <div class="right-panel">
        <div class="pane">
          <div class="head">
            <span>SQL列表 {{ getCurrentCategoryName() }}</span>
            <div style="flex: 1;"></div>
            <el-button type="primary" @click="handleAddSql" size="small" style="margin-right: 12px;">
              <el-icon><Plus /></el-icon>新增SQL
            </el-button>
          </div>
          <div class="body">
            <el-form :inline="true" class="search-bar">
              <el-form-item>
                <el-input v-model="queryParams.keywords" placeholder="请输入SQL名称检索" style="width: 300px;" clearable />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="handleQuery">
                  <el-icon><Search /></el-icon>搜索
                </el-button>
                <el-button @click="resetQuery">
                  <el-icon><Refresh /></el-icon>重置
                </el-button>
              </el-form-item>
            </el-form>

            <el-table 
              :data="sqlList" 
              style="width: 100%" 
              v-loading="sqlLoading"
              height="calc(100vh - 280px)"
			  border
            >
              <el-table-column prop="name" label="SQL名称" />
			  <el-table-column prop="identifier" label="SQL标识" width="180" />
			  <el-table-column prop="exec" label="SQL执行" width="250" align="left" >
			    <template #default="scope">
			      <DictLabel v-model="scope.row.exec" code="sql_execute_type" />
			    </template>
			  </el-table-column>
              <el-table-column prop="sort" label="排序" width="80" align="center" />
              <el-table-column prop="updateTime" label="更新时间" width="180" />
              <el-table-column label="操作" width="220" fixed="right">
                <template #default="scope">
                  <el-button 
                    link 
                    type="primary" 
                    @click="handleEditSql(scope.row)"
                  >编辑</el-button>
                  <el-button 
                    link 
                    type="primary" 
                    @click="handleTestSql(scope.row)"
                  >测试</el-button>
                  <el-button 
                    link 
                    type="danger" 
                    @click="handleDeleteSql(scope.row)"
                  >删除</el-button>
                </template>
              </el-table-column>
            </el-table>
			<div>
				<el-pagination
				  v-if="total > 0"
				  :total="total"
				  v-model:current-page="queryParams.cur"
				  v-model:page-size="queryParams.limit"
				  class="pagination"
				  @current-change="getSqlList"
				/>
			</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 右键菜单 -->
    <div 
      v-show="contextMenuVisible" 
      class="context-menu"
      :style="{
        left: contextMenuPosition.x + 'px',
        top: contextMenuPosition.y + 'px'
      }"
    >
      <ul>
        <li @click="handleAddSubCategory(currentRow)">
          <el-icon><Plus /></el-icon>
          新增子类别
        </li>
        <li @click="handleEditCategory(currentRow)">
          <el-icon><Edit /></el-icon>
          编辑
        </li>
        <li @click="handleDeleteCategory(currentRow)">
          <el-icon><Delete /></el-icon>
          删除
        </li>
      </ul>
    </div>

    <!-- 点击空白处关闭右键菜单 -->
    <div 
      v-show="contextMenuVisible" 
      class="context-menu-mask" 
      @click="closeContextMenu"
      @contextmenu.prevent
    />

    <!-- SQL类别表单弹窗 -->
    <sql-category-form-dialog
		ref="sqlCategoryFormDialogRef"
		@closeDialog="getCategoryList"
    />

    <!-- SQL表单抽屉 -->
    <sql-form-drawer
		ref="sqlFormDrawerRef"
		@closeDialog="getSqlList"
    />

    <!-- SQL测试抽屉 -->
    <sql-test-drawer
		ref="sqlTestDrawerRef"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import type { SqlCategory, SqlVO } from '@/api/biz/sql';
import SqlAPI from '@/api/biz/sql';
import { recurOptions } from "@/utils/TreeUtil";
import SqlCategoryFormDialog from './components/SqlCategoryFormDialog.vue';
import SqlFormDrawer from './components/SqlFormDrawer.vue';
import SqlTestDrawer from './components/SqlTestDrawer.vue';

// 树形配置
const defaultProps = {
  children: 'children',
  label: 'name'
};

const treeRef = ref();
const sqlCategoryFormDialogRef = ref();
const sqlFormDrawerRef = ref();
const sqlTestDrawerRef = ref();

// 查询参数
const queryParams = reactive({
  keywords: '',
  categoryId: '',
  cur: 1,
  limit: 10
});

// 数据列表
const categoryList = ref<SqlCategory[]>([]);
const categoryTreeData = ref<any[]>([]);
const sqlList = ref<SqlVO[]>([]);
const total = ref(0);

// 加载状态
const categoryLoading = ref(false);
const sqlLoading = ref(false);

// 右键菜单
const contextMenuVisible = ref(false);
const contextMenuPosition = reactive({ x: 0, y: 0 });
const currentRow = ref<SqlCategory | null>(null);

// 弹窗控制
const categoryDialog = reactive({
  visible: false,
  title: '',
  data: {} as SqlCategory
});

const sqlDialog = reactive({
  visible: false,
  title: '',
  data: {} as SqlVO
});

const testDialog = reactive({
  visible: false,
  data: {} as SqlVO
});

// 获取SQL类别列表并转换为树形结构
const getCategoryList = async () => {
  try {
    categoryLoading.value = true;
    const res = await SqlAPI.getCategoryList({ keywords: '' });
    categoryList.value = res;
    categoryTreeData.value = recurOptions(res, '');
  } catch (error) {
    console.error('获取SQL类别列表失败:', error);
  } finally {
    categoryLoading.value = false;
  }
};

// 获取SQL列表
const getSqlList = async () => {
  try {
    sqlLoading.value = true;
    const data = await SqlAPI.getPage(queryParams);
	sqlList.value = data.list;
	total.value = data.totalRow;
  } catch (error) {
    console.error('获取SQL列表失败:', error);
  } finally {
    sqlLoading.value = false;
  }
};

// 处理类别点击
const handleCategoryClick = (data: any) => {
  queryParams.categoryId = data?.id;
  getSqlList();
};

// 获取当前类别名称
const getCurrentCategoryName = () => {
  if (!queryParams.categoryId) return '';
  const category = categoryList.value.find(item => item.id === queryParams.categoryId);
  return category ? ` - ${category.name}` : '';
};

// 处理右键菜单
const handleContextMenu = (event: MouseEvent, data: any) => {
  event.preventDefault();
  contextMenuVisible.value = true;
  contextMenuPosition.x = event.clientX;
  contextMenuPosition.y = event.clientY;
  currentRow.value = data;
};

// 关闭右键菜单
const closeContextMenu = () => {
  contextMenuVisible.value = false;
};

// 新增类别
const handleAddCategory = () => {
  sqlCategoryFormDialogRef.value.openDialog(null, 'add');
};

// 新增子类别
const handleAddSubCategory = (parentNode: any) => {
  const category = {
    parentId: parentNode?.id || ''
  };
  sqlCategoryFormDialogRef.value.openDialog(category, 'add');
  closeContextMenu();
};

// 编辑类别
const handleEditCategory = (row: SqlCategory | null) => {
  if (!row) return;
  sqlCategoryFormDialogRef.value.openDialog(row,'edit')
  closeContextMenu();
};

// 删除类别
const handleDeleteCategory = (row: SqlCategory | null) => {
  if (!row) return;
  ElMessageBox.confirm('确认要删除该类别吗？', '警告', {
    type: 'warning'
  }).then(async () => {
    await SqlAPI.deleteCategoryByIds(row.id!);
    ElMessage.success('删除成功');
    getCategoryList();
    closeContextMenu();
  });
};

// 新增SQL
const handleAddSql = () => {
  if (!queryParams.categoryId) {
    ElMessage.warning('请先选择类别');
    return;
  }
  sqlFormDrawerRef.value.openDialog(null,'add');
};

// 编辑SQL
const handleEditSql = (row: SqlVO) => {
  sqlFormDrawerRef.value.openDialog(row,'edit');
};

// 删除SQL
const handleDeleteSql = (row: SqlVO) => {
  ElMessageBox.confirm('确认要删除该SQL吗？', '警告', {
    type: 'warning'
  }).then(async () => {
    await SqlAPI.deleteByIds(row.id!);
    ElMessage.success('删除成功');
    getSqlList();
  });
};

// 测试SQL
const handleTestSql = (row: SqlVO) => {
  sqlTestDrawerRef.value.openDialog(row)
};

// 搜索
const handleQuery = () => {
  queryParams.cur = 1;
  getSqlList();
};

// 重置
const resetQuery = () => {
  // 清空查询参数
  queryParams.keywords = '';
  queryParams.categoryId = '';
  // 取消树节点选中状态
  treeRef.value?.setCurrentKey(null);
  // 重新加载列表
  handleQuery();
};

onMounted(() => {
  getCategoryList();
  handleQuery();
});
</script>

<style lang="scss" scoped>
.context-menu {
  position: fixed;
  z-index: 9999;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-light);
  border-radius: 4px;
  box-shadow: var(--el-box-shadow-light);
  
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    
    li {
      padding: 8px 16px;
      display: flex;
      align-items: center;
      gap: 8px;
      cursor: pointer;
      color: var(--el-text-color-regular);
      
      &:hover {
        background-color: var(--el-color-primary-light-9);
        color: var(--el-color-primary);
      }
      
      .el-icon {
        font-size: 16px;
      }
    }
  }
}

.context-menu-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9998;
}

.pagination {
  margin-top: 16px;
  justify-content: flex-end;
}

.left-panel {
  width: 300px;
  margin-right: 16px;
}

.right-panel {
  width: calc(100% - 316px);
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-right: 8px;
  
  .node-actions {
    opacity: 0;
    transition: opacity 0.2s;
    
    .el-button {
      padding: 2px 4px;
    }
  }
  
  &:hover .node-actions {
    opacity: 1;
  }
}

:deep(.el-tree-node__content) {
  height: 32px;
}

:deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
}

:deep(.el-table th.el-table__cell) {
	background-color: #fafafa;
	background-image: url();
	background-image: -webkit-linear-gradient(top, #f2f2f2 0, #fafafa 100%);
	background-image: -moz-linear-gradient(top, #f2f2f2 0, #fafafa 100%);
	background-image: -o-linear-gradient(top, #f2f2f2 0, #fafafa 100%);
	background-image: linear-gradient(to bottom, #f2f2f2 0, #fafafa 100%);
	font-size: 12px;
}
</style>